﻿//using MyWeb.ScheduledTasks.Models;
using MyWeb.ScheduledTasks.Models;
using MyWeb.ScheduledTasks.Services;
using Newtonsoft.Json;
using Quartz;
using Quartz.Impl;
using Quartz.Impl.Triggers;
using System.Reflection;
using static MyWeb.ScheduledTasks.Protos.ResponseJob.Types;

namespace MyWeb.ScheduledTasks.Business.Job
{
    public class ClassLibraryJob : IJob
    {
        private IJobsService _quartzService;
        private IServiceProvider _serviceProvider;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="serviceProvider"></param>
        /// <param name="quartzService"></param>
        public ClassLibraryJob(IServiceProvider serviceProvider, IJobsService quartzService)
        {
            this._quartzService = quartzService;
            this._serviceProvider = serviceProvider;
        }
        public async Task Execute(IJobExecutionContext context)
        {
            AbstractTrigger? trigger = (context as JobExecutionContextImpl).Trigger as AbstractTrigger;
            TaskLog log = new TaskLog();
            log.BeginDate = DateTime.Now;
            log.TaskName = trigger.Name;
            log.GroupName = trigger.Group;
            log.TaskType = 1;

            
            try
            {
                Jobs? jobs = (await _quartzService.GetJobs(a => a.TaskName == trigger.Name && a.GroupName == trigger.Group)).FirstOrDefault();
                if (jobs == null)
                {
                    jobs = (await _quartzService.GetJobs(a => a.TaskName == trigger.JobName && a.GroupName == trigger.JobGroup)).FirstOrDefault();
                }
                if (jobs == null)
                {
                    throw new Exception($"组别:{trigger.JobGroup}/{trigger.Group},名称:{trigger.JobName}/{trigger.Name},的作业未找到,可能已被移除", new Exception("task is not exists!"));
                }
                log.JobsId = jobs.Id;
                log.TaskName = jobs.TaskName;
                log.GroupName = jobs.GroupName;
                if (string.IsNullOrEmpty(jobs.DllName) || string.IsNullOrEmpty(jobs.DllClassName) || string.IsNullOrEmpty(jobs.DllActionName))
                {
                    throw new Exception($"组别:{trigger.JobGroup}/{trigger.Group},名称:{trigger.JobName}/{trigger.Name},DLL名称/DLL类名/DLL方法名 不允许为空!", new Exception("invalid parameter"));
                }

                log.ExecTarget = jobs.DllName + "." + jobs.DllClassName + "." + jobs.DllActionName;
                log.RequestParam = jobs.Parameter;
                Assembly ass = Assembly.Load(jobs.DllName);//DLL名称
                var param = JsonConvert.DeserializeObject<List<object>>(jobs.Parameter);
                List<Type> types = new List<Type>();
                if (param != null)
                {
                    foreach (var p in param)
                    {
                        types.Add(p.GetType());
                    }
                }
                // 存储类 // 通过类名获取同名类
                Type? type = ass.GetType(jobs.DllClassName);
                // 存储类的实例 // 创建实例  
                object? obj = Activator.CreateInstance(type);

                // 获取方法信息
                MethodInfo? method = type.GetMethod(jobs.DllActionName, types.ToArray());
                if (method == null)
                {
                    // 输出返回值
                    throw new Exception($"未获取到执行方法!");
                }
                //object[] parameters = param.ToArray();
                object? result = null;
                if (param != null)
                {
                    result = method.Invoke(obj, param.ToArray());     // 调用方法，有参数，有返回值
                }
                else
                {
                    result = method.Invoke(obj, null);     // 调用方法，有参数，有返回值
                }
                
                log.ResponseParam = JsonConvert.SerializeObject(result);
                log.LogType = "success";
                //var services = _serviceProvider.GetServices<IJobService>();
                //var service = services.Where(a => a.GetType().Name == taskOptions.DllClassName).FirstOrDefault();
                //if (service != null)
                //{
                //    httpMessage = service.ExecuteService(taskOptions.ApiParameter);
                //}
                //else
                //{
                //    httpMessage = "未找到对应类型,请检查是否注入!";
                //}
            }
            catch (Exception ex)
            {
                log.LogType = "error:" + (ex.InnerException is null ? ex.Message : ex.InnerException.Message);
                log.ResponseParam = ex.Message;
            }
            finally
            {
                log.EndDate = DateTime.Now;
                try
                {
                    await _quartzService.AddTaskLog(log);
                }
                catch { }
            }
            return;
        }
    }
}
